﻿#region copyright info
//------------------------------------------------------------------------------
// <copyright company="ChaosStudio">
//     Copyright (c) 2002-2010 巧思工作室.  All rights reserved.
//     Contact:		MSN:zhouyu@cszi.com , QQ:478779122
//		Link:				http://www.69sea.com http://www.cszi.com
// </copyright>
//------------------------------------------------------------------------------
#endregion

using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Net;

namespace CS.Utility.FileManage
{
    /// <summary>
    /// 数据(一般为数据库里的记录)与文本文件的相关处理[只处理文本文件]
    /// ver: 0.10
    /// </summary>
    /// 
    /// <description class = "CS.File.DataFileHelper">
    ///   
    /// </description>
    /// 
    /// <history>
    ///     Create      :	    atwind , 创建 , 2010/2/18 13:11:29 ;
    ///  </history>
    public class DataFile
    {

        private string _encoding = "UTF-8";
        /// <summary>
        /// 编码格式，默认是UTF-8
        /// </summary>
        public string Encoding
        {
            get { return _encoding; }
            set { _encoding = value; }
        }

        private string _separator = "\t";
        /// <summary>
        /// 内容分隔符，默认是Tab[\t]
        /// </summary>
        public string Separator
        {
            get { return _separator; }
            set { _separator = value; }
        }

        private bool _isOverWrite = true;
        /// <summary>
        /// 文件已存在时重写
        /// </summary>
        public bool IsOverWrite
        {
            get { return _isOverWrite; }
            set { _isOverWrite = value; }
        }


        #region 保存文件 Save IList ,DataSet,IDataReader

        /// <summary>
        /// 保存文件至运行代码根目录的Archives文件夹下
        /// </summary>
        /// <param name="list">内容List <para>IEnumerable<string[]></para></param>
        /// <param name="fileName">文本文件名</param>
        /// <returns>成功与否</returns>
        public bool Save(IEnumerable<string[]> list, string fileName)
        {
            return Save(list, null, null, fileName);
        }

        /// <summary>
        /// 保存文件至运行代码根目录的Archives文件夹下并按日期存放
        /// </summary>
        /// <param name="list">内容List <para>IEnumerable<string[]></para></param>
        /// <param name="dateFolderPattern">null时保存至basePath,有格式时间命名文件夹，如:yyyyMMdd</param>
        /// <param name="fileName">文件名字</param>
        /// <returns>成功与否</returns>
        public bool Save(IEnumerable<string[]> list, string dateFolderPattern, string fileName)
        {
            return Save(list, null, dateFolderPattern, fileName);
        }

        /// <summary>
        /// 保存至文件
        /// </summary>
        /// <param name="list">内容List</param>
        /// <param name="basePath">文件保存的基础路径</param>
        /// <param name="dateFolderPattern">null时保存至basePath,有格式时间命名文件夹，如:yyyyMMdd</param>
        /// <param name="fileName">文本文件名</param>
        /// <returns>成功与否</returns>
        public bool Save(IEnumerable<string[]> list, string basePath, string dateFolderPattern, string fileName)
        {
            var folder = string.IsNullOrEmpty(basePath) ? new FolderHelper():  new FolderHelper(basePath);
            bool isDateFormat;
            if(string.IsNullOrEmpty(dateFolderPattern))
            {
                isDateFormat = false;
            }
            else
            {
                isDateFormat = true;
                folder.DateFormater = dateFolderPattern;
            }
            var fullPath = folder.Create(isDateFormat);
            if (!fileName.Contains("."))
            {
                fileName = string.Format("{0}.txt", fileName);
            }
            try
            {
                if (!File.Exists(fileName) || _isOverWrite)
                {
                    using (var fs = new FileStream(string.Format(@"{0}\{1}", fullPath, fileName), FileMode.Create, FileAccess.Write))
                    {
                        using (var sw = new StreamWriter(fs, System.Text.Encoding.GetEncoding(_encoding)))
                        {
                            foreach (string[] data in list)
                            {
                                var row = string.Join(_separator, data);
                                sw.WriteLine(row);
                            }
                            sw.Flush();
                        }
                    }
                    return true;
                }
            }
            catch (Exception)
            {
                throw;
            }

            return false;
        }

        /// <summary>
        /// 保存DataReader至文本存于运行代码根根目录Archives下按yyyyMMdd命名存档文件夹
        /// </summary>
        /// <param name="dr">数据源</param>
        /// <param name="fileName">文本文件名</param>
        /// <returns>是否成功</returns>
        public bool Save(IDataReader dr, string fileName)
        {
            return Save(dr, null, "yyyyMMdd", fileName);
        }

        /// <summary>
        /// 保存DataReader至文本存于运行代码根根目录Archives下
        /// </summary>
        /// <param name="dr">数据源</param>
        /// <param name="dateFolderPattern">null时保存至basePath,有格式时间命名文件夹，如:yyyyMMdd</param>
        /// <param name="fileName">文本文件名</param>
        /// <returns>是否成功</returns>
        public bool Save(IDataReader dr, string dateFolderPattern, string fileName)
        {
            return Save(dr, null, dateFolderPattern, fileName);
        }

        /// <summary>
        /// 保存DataReader至文本
        /// </summary>
        /// <param name="dr">数据源</param>
        /// <param name="basePath">基础路径,null时保存至运行根目录下的Archives下</param>
        /// <param name="dateFolderPattern">null时保存至basePath,有格式时间命名文件夹，如:yyyyMMdd</param>
        /// <param name="fileName">文本文件名</param>
        /// <returns>是否成功</returns>
        public bool Save(IDataReader dr, string basePath, string dateFolderPattern, string fileName)
        {
            if (dr != null)
            {
                var list = new List<string[]>();
                while (dr.Read())
                {
                    var field = new List<string>(dr.FieldCount);
                    for (var i = 0; i < dr.FieldCount; i++)
                    {
                        field.Add(dr[i] + "");
                    }
                    list.Add(field.ToArray());
                }
                return Save(list, basePath, dateFolderPattern, fileName);
            }
            return false;
        }


        #endregion


        #region 获取流中文件内容

        /// <summary>
        /// 获取流中文件内容
        /// </summary>
        /// <param name="stream">流</param>
        /// <returns>文件内容</returns>
        protected IList<string[]> GetStreamContent(Stream stream)
        {
            using (var sr = new StreamReader(stream, System.Text.Encoding.GetEncoding(_encoding)))
            {
                var list = new List<string[]>();
                string line;
                while ((line = sr.ReadLine()) != null && line.Length > 0)
                {
                    string[] info = line.Split(_separator.ToCharArray());
                    list.Add(info);
                }
                return list;
            }
        }

        #endregion


        #region 获取本地文件内容

        /// <summary>
        /// 获取本地文件内容
        /// </summary>
        /// <param name="fullFileName">文件全路径(包含文件名称)</param>
        /// <param name="status">文件的状态</param>
        /// <returns>文件内容</returns>
        public IList<string[]> ReadFile(string fullFileName, out FileStatusType status)
        {
            try
            {
                if (File.Exists(fullFileName))
                {
                    using (var fs = new FileStream(fullFileName, FileMode.Open, FileAccess.Read))
                    {
                        status = FileStatusType.ReadSuccess;
                        return GetStreamContent(fs);
                    }
                }
                status = FileStatusType.FileNotExist;
            }
            catch (Exception)
            {
                status = FileStatusType.Exception;
                throw;
            }
            return null;
        }


        #region 获取http文件内容

        /// <summary>
        /// 通过TPC协议获取http文件内容
        /// </summary>
        /// <param name="url">文件Url地址</param>
        /// <param name="status">获取状态</param>
        /// <returns>文件内容</returns>
        public IList<string[]> ReadFileByTcp(string url, out FileStatusType status)
        {
            status = FileStatusType.Unknow;
            try
            {
                var request = WebRequest.Create(url);
                //var request = HttpWebRequest.Create(url);
                request.Method = "Get";
                var response = (HttpWebResponse)request.GetResponse();
                if (response.StatusCode == HttpStatusCode.OK)
                {
                    using (var stream = response.GetResponseStream())
                    {
                        var list = GetStreamContent(stream);
                        status = FileStatusType.DownloadSuccess;
                        return list;
                    }
                }
                if (response.StatusCode != HttpStatusCode.NotFound)
                {
                    status = FileStatusType.DownloadFailed;
                }
            }
            catch (WebException we)
            {
                throw;
            }
            catch (Exception ex)
            {
                throw;
            }
            return null;
        }

        #endregion



        #endregion


    }

    /// <summary>
    /// 文件状态枚举
    /// </summary>
    public enum FileStatusType
    {
        /// <summary>
        /// 文件不存在
        /// </summary>
        FileNotExist = 0,

        /// <summary>
        /// 文件读取成功
        /// </summary>
        ReadSuccess = 1,

        /// <summary>
        /// 网络读取成功
        /// </summary>
        DownloadSuccess = 2,

        /// <summary>
        /// 网络读取失败
        /// </summary>
        DownloadFailed = 3,


        /// <summary>
        /// 不确定
        /// </summary>
        Unknow = 99,

        /// <summary>
        /// 文件读取发生异常
        /// </summary>
        Exception = 999,

    }
}